#include <algorithm>
#include <array>
#include <cstdint>
#include <iostream>
#include <ranges>
#include <vector>

#define func auto

using i64 = int64_t;
using i32 = int32_t;

template<class ...Args>
void input(Args&&...args){
    (std::cin>>...>>args);
}

template<class T>
T input(){
    T tmp;
    std::cin>>tmp;
    return tmp;
}

template<class ...Args>
func print(Args...args){
    (std::cout<<...<<args);
}

const i64 max_n = 100000 + 5, mod{998244353};
i64 w[max_n], a[max_n], dfs_in[max_n], dfs_out[max_n];
std::vector<i64> sons[max_n];

template<i64 size>
class Segtree{
private:
    std::array<i64, size*4> nodes{};
    std::array<i64, size*4> lazy_mul;
    void build(const i64 (&arr)[], const i64 l, const i64 r, const i64 n){
        if(l==r){
            nodes[n]=arr[l];
            return;
        }

        const i64 mid {(l+r)/2};
        build(arr, l, mid, n*2);
        build(arr, mid+1, r, n*2+1);

        nodes[n] = nodes[n*2] + nodes[n*2+1];
    }

    void update_mul(const i64 ul, const i64 ur, const i64 l, const i64 r,const i64 n){
        if(lazy_mul[n]!=1){
            // nodes[]
        }

        if(r < ul || ur < l){
            return;
        }
    }
public:
    Segtree(const i64 (&arr)[], const i64 n){
        build(arr, 1, n, 1);
        std::fill(lazy_mul.begin(), lazy_mul.end(), 1);
    }

};

//testing
Segtree<50> st(a,2);

i64 mod_pow(i64 b, i64 e, const i64 m = mod){
    b %= mod;
    i64 res {1};
    while(e!=0){
        if(e&1){
            res = (res * b) % mod;
        }
        b = (b * b) % mod;
        e>>=1;
    }
    return res % mod;
}

i64 inverse(const i64 b, const i64 m = mod){
    return mod_pow(b, m-2, m);
}

i64 mult_mod(const i64 a, const i64 b, const i64 m = mod){
    return ((a % m) * inverse(b)) % m;
}

func dfs(const i64 u, const i64 prob)->i64{
    if(sons[u].empty()){
        return (prob * a[u]) % mod;
    }

    const i64 sum_u = [&u]()->i64{
        i64 ret{};
        for(const i64 v:sons[u]){
            ret = (ret + w[v]) % mod;
        }
        return ret;
    }();
    
    const i64 exp_score = [&prob, &sum_u, &u]()->i64{
        i64 ret {};
        for(const auto v:sons[u]){
            // const i64 new_prob = prob * w[v] / sum_u;
            const i64 new_prob = mult_mod(prob * w[v], sum_u);
            ret = (ret + dfs(v, new_prob)) % mod;
        }
        return ret;
    }();
    
    return (exp_score + prob * a[u]) % mod;
}

func main()->int{
    const i64 n = input<i64>();
    for(const i64 i:std::ranges::views::iota(2,n+1)){
        const i64 father = input<i64>();
        sons[father].push_back(i);
    }
    std::for_each_n(w+1, n,[](i64 &wi){
        input(wi);
    });
    std::for_each_n(a+1, n, [](i64 &ai){
        input(ai);
    });

    print(dfs(1, 1), '\n');

    const i64 q = input<i64>();

    std::ranges::for_each(std::ranges::views::iota(0ll, q), [](auto){
        const i64 u{input<i64>()};
        w[u] = input<i64>();
        a[u] = input<i64>();
        print(dfs(1,1),'\n');
    });
}